-
-
Notifications
You must be signed in to change notification settings - Fork 462
1559: Can't resolve 'tailwindcss/version.js' #1566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add `version` field to configuration schema and documentation, specifying the Tailwind CSS version to use (default: 4)
- more robust .json import
🦋 Changeset detectedLatest commit: e7f5931 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
""" WalkthroughThis update removes the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant ConfigFile
participant InitFile
participant ReactApp
User->>CLI: Run init/build/dev/register
CLI->>ConfigFile: Read/validate config.json
CLI->>InitFile: Generate/update init.tsx (ThemeInit)
CLI->>ReactApp: User imports ThemeInit at root
ReactApp->>ThemeInit: Render at runtime
ThemeInit->>Store: Sync config (dark, prefix, version)
Estimated code review effort4 (~100 minutes) The changes are extensive, affecting CLI commands, configuration management, runtime initialization, documentation, and package exports. There are major refactors, new files, and deletions, but the changes are mostly focused on a specific feature set and are well-scoped. Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
packages/ui/src/theme/mode-script.tsxOops! Something went wrong! :( ESLint: 8.57.0 ESLint couldn't find the plugin "eslint-plugin-react". (The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "/packages/ui".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
The plugin "eslint-plugin-react" was referenced from the config file in "packages/ui/.eslintrc.cjs". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. packages/ui/src/theme/mode-script.test.tsxOops! Something went wrong! :( ESLint: 8.57.0 ESLint couldn't find the plugin "eslint-plugin-react". (The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "/packages/ui".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
The plugin "eslint-plugin-react" was referenced from the config file in "packages/ui/.eslintrc.cjs". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (3)
🪛 Biome (1.9.4)packages/ui/src/theme/mode-script.tsx[error] 71-71: Avoid passing content using the dangerouslySetInnerHTML prop. Setting content using code can expose users to cross-site scripting (XSS) attacks (lint/security/noDangerouslySetInnerHtml) 🚧 Files skipped from review as they are similar to previous changes (2)
🧰 Additional context used🪛 Biome (1.9.4)packages/ui/src/theme/mode-script.tsx[error] 71-71: Avoid passing content using the dangerouslySetInnerHTML prop. Setting content using code can expose users to cross-site scripting (XSS) attacks (lint/security/noDangerouslySetInnerHtml) ⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (5)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
- add `ThemeConfig` in apps/[storybook, web] - enforce schema `version` to [3,4]
Hi @SutuSebastian, |
@trzcina just couple of migration scripts left and thats it, things looks pretty stable so far. Btw, what does this have to do with |
Thanks for the info. What I meant is that in my project, I replaced this file by overriding the Webpack config — in my case, within the Next.js configuration.
|
…zation documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (1)
packages/ui/src/cli/commands/setup-vscode.ts (1)
149-149
: Duplicate of previous encoding remark
See above – apply identical change here for consistency.
🧹 Nitpick comments (13)
packages/ui/src/cli/commands/setup-vscode.ts (1)
101-101
: Explicitly pass encoding when writing JSON
fs.writeFile
defaults to UTF-8, but being explicit prevents accidental regression if Node ever changes defaults or if someone swaps this call for the synchronous variant.- await fs.writeFile(vscodeSettingsFilePath, cjson.stringify(settings, null, 2)); + await fs.writeFile( + vscodeSettingsFilePath, + cjson.stringify(settings, null, 2), + { encoding: "utf-8" }, + );(Same comment applies to the
extensions.json
write on line 149.)apps/web/app/layout.tsx (1)
6-6
: Prefer path alias over brittle relative import
../.flowbite-react/init
works today, but any directory shuffle (e.g. movinglayout.tsx
) will silently break the import. Adding a@flowbite-init
alias intsconfig.json
(and the Next 13 alias section) keeps the path stable:-import { ThemeInit } from "../.flowbite-react/init"; +import { ThemeInit } from "@flowbite-init";This also avoids importing from a dot-prefixed directory which some tooling skips by default.
packages/ui/src/cli/commands/setup-output-directory.ts (1)
4-8
: Good JSDoc—add return type for completenessNice touch documenting the helper. Consider stating the (implicit)
Promise<void>
return to help IDEs display richer hints:- * This function checks if the `.flowbite-react` directory exists and creates it if it does not. + * This function checks if the `.flowbite-react` directory exists and creates it if it does not. + * + * @returns {Promise<void>}apps/web/content/docs/customize/custom-components.mdx (1)
24-34
: Update surrounding docs to list new fieldsThe JSON example now introduces
dark
,tsx
, andversion
, but the bullet list above still enumerates onlypath
,rsc
, andtsx
. Readers may miss thatversion
is mandatory. Please adjust the description list accordingly.packages/ui/src/helpers/resolve-theme.ts (1)
70-70
: Guard against unsupportedversion
values
getVersion()
is expected to return3 | 4
, but nothing prevents downstream code from writing an arbitrary number/string into the store. A defensive check avoids silent mis-behaviour:-const version = getVersion(); +const version = getVersion(); +if (version !== 3 && version !== 4) { + throw new Error(`Unsupported Tailwind version "${version}". Expected 3 or 4.`); +}packages/ui/src/cli/utils/get-tailwind-version.ts (1)
11-24
: Solid implementation with good error handling.The function properly handles package detection, version parsing, and validation. The error messages are clear and the typing is precise.
Consider making the version parsing more robust:
- const major = parseInt(tailwindcssPackageJson.version.split(".")[0], 10); + const versionParts = tailwindcssPackageJson.version.split("."); + const major = versionParts.length > 0 ? parseInt(versionParts[0], 10) : NaN;This would handle edge cases where the version string might not follow expected format.
packages/ui/src/cli/utils/get-module-package-json.ts (1)
16-21
: Consider adding optional error logging for debugging.The fallback mechanism and error handling approach are solid. However, the empty catch blocks might make troubleshooting difficult during development.
Consider adding optional debug logging:
} catch { try { return (await import(`${packageName}/package.json`)).default; - } catch { + } catch (error) { + // Optional: Add debug logging + // console.debug(`Failed to resolve ${packageName}/package.json:`, error); return null; } }packages/ui/src/cli/commands/setup-gitignore.ts (1)
21-24
: Consider documenting the setTimeout delay reasoning.The simplified content comparison and improved logging are excellent improvements. However, the 10ms delay in setTimeout might benefit from a comment explaining its purpose.
Consider adding a comment to explain the delay:
- setTimeout(() => fs.writeFile(gitIgnoreFilePath, content), 10); + // Small delay to avoid potential file system race conditions + setTimeout(() => fs.writeFile(gitIgnoreFilePath, content), 10);packages/ui/src/cli/utils/build-class-list.ts (1)
8-27
: Update JSDoc to document the version parameter.The function signature correctly adds the
version
parameter with proper type constraints, but the JSDoc comment should be updated to document this new parameter.* @param {Object} options - The options for building the class list. * @param {string[]} options.components - The components to include in the class list. * @param {boolean} options.dark - Whether to include dark mode classes. * @param {string} options.prefix - The prefix to apply to the class names. + * @param {3 | 4} options.version - The Tailwind CSS version to use for class generation. * @returns {string[]} The sorted list of CSS classes.
packages/ui/src/cli/commands/install.ts (1)
13-21
: Improve error message clarity for package manager detection.The fallback logic is sound, but the error message could be more informative about the fallback behavior.
- if (!pm) { - console.error("Could not detect package manager"); - } + if (!pm) { + console.warn("Could not detect package manager, falling back to npm"); + }packages/ui/src/cli/commands/setup-config.ts (2)
51-60
: Consider optimizing component validation.The component validation creates a new validator function on each invalid component check. Consider extracting it outside the condition:
- const isValidComponent = (component: unknown) => - typeof component === "string" && - component.trim() !== "" && - (component === "*" || - COMPONENT_TO_CLASS_LIST_MAP[component as keyof typeof COMPONENT_TO_CLASS_LIST_MAP] !== undefined); - - if (newConfig.components.some((component) => !isValidComponent(component))) { + if (newConfig.components.some((component) => !isValidComponent(component))) {And define
isValidComponent
at the function scope or as a separate utility.
82-85
: Version validation might be too strict.The version validation always overwrites the user's version with the detected version. This might be intentional for consistency, but it prevents users from manually setting a different Tailwind version if needed (e.g., during migration).
Consider whether this strict enforcement is necessary or if a warning would suffice.
packages/ui/src/cli/commands/setup-init.ts (1)
13-40
: Consider conditional TypeScript directives for JSX files.The template includes TypeScript-specific directives (
// @ts-nocheck
) even when generating.jsx
files. Consider making this conditional:const content = ` /* eslint-disable */ -// @ts-nocheck +${config.tsx ? "// @ts-nocheck" : ""} // biome-ignore-all lint: auto-generated file `.trim();Otherwise, the template structure and path determination logic looks good.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (52)
.changeset/tricky-planes-shake.md
(1 hunks).github/actions/setup/action.yml
(1 hunks)apps/storybook/.flowbite-react/config.json
(1 hunks)apps/storybook/.flowbite-react/init.tsx
(1 hunks)apps/storybook/.storybook/preview.tsx
(2 hunks)apps/storybook/tsconfig.json
(1 hunks)apps/web/.flowbite-react/config.json
(1 hunks)apps/web/.flowbite-react/init.tsx
(1 hunks)apps/web/app/layout.tsx
(2 hunks)apps/web/content/docs/customize/config.mdx
(5 hunks)apps/web/content/docs/customize/custom-components.mdx
(1 hunks)apps/web/content/docs/customize/dark-mode.mdx
(2 hunks)apps/web/content/docs/customize/prefix.mdx
(2 hunks)apps/web/content/docs/getting-started/cli.mdx
(2 hunks)package.json
(1 hunks)packages/ui/package.json
(1 hunks)packages/ui/rollup.config.js
(0 hunks)packages/ui/schema.json
(2 hunks)packages/ui/scripts/generate-metadata.ts
(2 hunks)packages/ui/src/cli/commands/build.ts
(1 hunks)packages/ui/src/cli/commands/create.ts
(2 hunks)packages/ui/src/cli/commands/dev.ts
(4 hunks)packages/ui/src/cli/commands/ensure-tailwind.ts
(1 hunks)packages/ui/src/cli/commands/generate-class-list.ts
(0 hunks)packages/ui/src/cli/commands/help.ts
(0 hunks)packages/ui/src/cli/commands/init.ts
(1 hunks)packages/ui/src/cli/commands/install.ts
(2 hunks)packages/ui/src/cli/commands/patch.ts
(0 hunks)packages/ui/src/cli/commands/register.ts
(2 hunks)packages/ui/src/cli/commands/setup-class-list.ts
(1 hunks)packages/ui/src/cli/commands/setup-config.ts
(1 hunks)packages/ui/src/cli/commands/setup-gitignore.ts
(1 hunks)packages/ui/src/cli/commands/setup-init.ts
(1 hunks)packages/ui/src/cli/commands/setup-output-directory.ts
(1 hunks)packages/ui/src/cli/commands/setup-patch.ts
(0 hunks)packages/ui/src/cli/commands/setup-plugin.ts
(1 hunks)packages/ui/src/cli/commands/setup-register.ts
(2 hunks)packages/ui/src/cli/commands/setup-tailwind.ts
(2 hunks)packages/ui/src/cli/commands/setup-vscode.ts
(4 hunks)packages/ui/src/cli/consts.ts
(1 hunks)packages/ui/src/cli/main.ts
(2 hunks)packages/ui/src/cli/utils/build-class-list.ts
(1 hunks)packages/ui/src/cli/utils/get-config.ts
(1 hunks)packages/ui/src/cli/utils/get-module-package-json.ts
(1 hunks)packages/ui/src/cli/utils/get-package-json.ts
(1 hunks)packages/ui/src/cli/utils/get-tailwind-version.ts
(1 hunks)packages/ui/src/helpers/get-tailwind-version.ts
(0 hunks)packages/ui/src/helpers/resolve-theme.test.ts
(1 hunks)packages/ui/src/helpers/resolve-theme.ts
(2 hunks)packages/ui/src/helpers/tailwind-merge.ts
(1 hunks)packages/ui/src/store/index.ts
(3 hunks)packages/ui/src/theme/config.tsx
(1 hunks)
💤 Files with no reviewable changes (6)
- packages/ui/rollup.config.js
- packages/ui/src/cli/commands/help.ts
- packages/ui/src/helpers/get-tailwind-version.ts
- packages/ui/src/cli/commands/setup-patch.ts
- packages/ui/src/cli/commands/generate-class-list.ts
- packages/ui/src/cli/commands/patch.ts
🧰 Additional context used
🧬 Code Graph Analysis (16)
packages/ui/src/helpers/resolve-theme.ts (1)
packages/ui/src/store/index.ts (1)
getVersion
(75-77)
packages/ui/src/cli/commands/setup-class-list.ts (1)
packages/ui/src/cli/consts.ts (1)
classListFilePath
(14-14)
packages/ui/src/cli/commands/setup-register.ts (1)
packages/ui/src/cli/consts.ts (1)
packageJsonFile
(8-8)
packages/ui/src/helpers/resolve-theme.test.ts (1)
packages/ui/src/store/index.ts (1)
setStore
(40-61)
packages/ui/src/cli/utils/get-tailwind-version.ts (1)
packages/ui/src/cli/utils/get-module-package-json.ts (1)
getModulePackageJson
(9-22)
apps/storybook/.flowbite-react/init.tsx (1)
apps/web/.flowbite-react/init.tsx (1)
ThemeInit
(18-20)
apps/web/.flowbite-react/init.tsx (1)
apps/storybook/.flowbite-react/init.tsx (1)
ThemeInit
(18-20)
packages/ui/src/theme/config.tsx (1)
packages/ui/src/store/index.ts (1)
StoreProps
(4-31)
packages/ui/src/helpers/tailwind-merge.ts (1)
packages/ui/src/store/index.ts (2)
getPrefix
(71-73)getVersion
(75-77)
packages/ui/src/cli/commands/ensure-tailwind.ts (1)
packages/ui/src/cli/utils/get-package-json.ts (1)
getPackageJson
(20-27)
packages/ui/src/cli/commands/setup-gitignore.ts (1)
packages/ui/src/cli/consts.ts (3)
classListFile
(3-3)processIdFile
(11-11)gitIgnoreFilePath
(16-16)
packages/ui/src/cli/commands/register.ts (3)
packages/ui/src/cli/commands/setup-output-directory.ts (1)
setupOutputDirectory
(9-16)packages/ui/src/cli/utils/get-config.ts (1)
getConfig
(13-15)packages/ui/src/cli/commands/setup-init.ts (1)
setupInit
(12-70)
packages/ui/src/cli/commands/install.ts (2)
packages/ui/src/cli/utils/get-package-json.ts (1)
getPackageJson
(20-27)packages/ui/src/cli/utils/get-module-package-json.ts (1)
getModulePackageJson
(9-22)
packages/ui/src/cli/commands/setup-init.ts (2)
packages/ui/src/cli/commands/setup-config.ts (1)
Config
(8-17)packages/ui/src/cli/consts.ts (2)
initFilePath
(17-17)initJsxFilePath
(18-18)
packages/ui/src/cli/commands/setup-config.ts (2)
packages/ui/src/cli/utils/get-tailwind-version.ts (1)
getTailwindVersion
(11-24)packages/ui/src/cli/consts.ts (1)
configFilePath
(15-15)
packages/ui/src/cli/commands/dev.ts (7)
packages/ui/src/cli/commands/setup-output-directory.ts (1)
setupOutputDirectory
(9-16)packages/ui/src/cli/utils/get-config.ts (1)
getConfig
(13-15)packages/ui/src/cli/commands/setup-init.ts (1)
setupInit
(12-70)packages/ui/src/cli/utils/find-files.ts (1)
findFiles
(26-94)packages/ui/src/cli/consts.ts (6)
allowedExtensions
(37-37)classListFilePath
(14-14)configFilePath
(15-15)initFilePath
(17-17)initJsxFilePath
(18-18)gitIgnoreFilePath
(16-16)packages/ui/src/cli/utils/build-class-list.ts (1)
buildClassList
(17-84)packages/ui/src/cli/commands/setup-gitignore.ts (1)
setupGitIgnore
(10-28)
🪛 Biome (1.9.4)
apps/storybook/.flowbite-react/init.tsx
[error] 3-3: failed to parse category "-all"
(suppressions/parse)
apps/web/.flowbite-react/init.tsx
[error] 3-3: failed to parse category "-all"
(suppressions/parse)
🔇 Additional comments (82)
packages/ui/src/cli/commands/setup-vscode.ts (1)
6-11
: Nice docs – thanks for the clarity!
The added JSDoc noticeably improves discoverability for CLI contributors..github/actions/setup/action.yml (1)
10-10
: 👍 Bun bumped to 1.2.18 – remember to keep@types/bun
in sync
CI and local environments will now run Bun 1.2.18.package.json
still pins@types/bun
at 1.2.4; consider upgrading to avoid type mismatches.apps/web/.flowbite-react/config.json (1)
8-9
: Verify thatversion
matches the Tailwind CSS major actually installed
"version": 3
drives runtime/theme behaviour. If the project upgrades Tailwind 4 later, forgetting to bump this field will lead to mismatched class maps.Request: double-check the Tailwind dependency across all workspaces and update this field (and others) consistently.
apps/web/app/layout.tsx (1)
63-66
: Validate thatThemeInit
is a client component
RootLayout
is a server component. Rendering a client component (ThemeInit
) inside it is valid, but only ifThemeInit
’s file begins with"use client"
. If that pragma is missing the build will fail withYou're importing a component that needs `use client`…
Please double-check the generated
init.(tsx|jsx)
file or add the directive.apps/storybook/.flowbite-react/config.json (1)
8-9
: Ensure Tailwind version matches the rest of the workspaceThe store default is
4
, whereas Storybook config sets"version": 3
. If Storybook consumes components built for v4 utilities, class names may be transformed incorrectly (seeconvertUtilitiesToV4
). Confirm Storybook really uses Tailwind v3 or bump the value to4
.packages/ui/src/helpers/resolve-theme.ts (1)
4-4
: 👍 Centralising version retrievalSwitching to
getVersion
removes redundant heuristics and keeps all state in the store.apps/storybook/tsconfig.json (1)
24-25
: LGTM! TypeScript configuration properly updated for new file structure.The changes correctly broaden the compilation scope to include all TypeScript files recursively, which is necessary for the new
.flowbite-react/init.tsx
file, while properly excluding build artifacts and dependencies.packages/ui/src/helpers/resolve-theme.test.ts (1)
21-21
: Good addition of version property to test the new version-aware theme system.The addition of
version: 3
to the store setup correctly tests the version-specific prefix application behavior, ensuring the new version-aware theme resolution system works as expected.packages/ui/src/cli/commands/setup-plugin.ts (1)
3-8
: Excellent documentation addition.The JSDoc comment clearly describes the function's purpose and behavior, improving code maintainability without altering the implementation.
packages/ui/src/cli/main.ts (2)
53-53
: Command list correctly updated to remove patch command.The removal of "patch" from the valid commands list is consistent with the elimination of the patching mechanism described in the PR objectives.
26-27
: installPackage function export verified
- Confirmed that
installPackage
is exported frompackages/ui/src/cli/commands/install.ts
.- Renaming in
packages/ui/src/cli/main.ts
(lines 26–27) and removal of the patch command align with the intended refactoring.All changes look good—approving.
packages/ui/src/cli/commands/create.ts (2)
168-168
: Simplification of writeFile call is acceptable.Removing the explicit
{ flag: "w" }
option is fine since the default behavior offs.writeFile
is to overwrite existing files, which matches the intended behavior.
5-5
: setupInit export verified and integration approved.
- Confirmed that
setupInit
is correctly exported frompackages/ui/src/cli/commands/setup-init.ts
.- The call to
setupInit(config)
increate.ts
aligns with the new initialization pattern.- Removing the explicit
{ flag: "w" }
fromfs.writeFile
relies on the default overwrite behavior and is acceptable.packages/ui/src/cli/commands/setup-tailwind.ts (2)
9-14
: Well-documented function purpose.The JSDoc clearly describes the function's behavior and aligns with the implementation.
27-32
: Clear and accurate documentation.The JSDoc properly explains the v4-specific setup process including file search and directive addition.
packages/ui/src/cli/commands/setup-register.ts (2)
6-12
: Comprehensive function documentation.The JSDoc thoroughly explains the postinstall script setup logic including both new and existing script scenarios.
29-29
: Good simplification by relying on default behavior.Removing the explicit write flag is appropriate since
fs.writeFile
defaults to overwriting files.packages/ui/src/cli/commands/setup-class-list.ts (2)
4-8
: Clear documentation of file management logic.The JSDoc accurately describes the function's file existence checking and creation behavior.
14-14
: Consistent simplification across the codebase.Removing the explicit write flag aligns with the cleanup pattern seen in other files.
packages/ui/src/helpers/tailwind-merge.ts (2)
3-3
: Good centralization of version access.Moving to store-based version retrieval improves performance by avoiding repeated file system access.
9-9
: Consistent with the new store-based architecture.The function call change aligns with the centralized version management approach.
apps/web/.flowbite-react/init.tsx (2)
12-16
: Configuration values look correct.The hardcoded config values align with the migration from patch-based to runtime initialization approach. The
version: 3
indicates Tailwind CSS v3 usage, which is appropriate for addressing the 'tailwindcss/version.js' resolution issue.
18-22
: Component implementation follows the expected pattern.The
ThemeInit
component correctly spreads the config toStoreInit
and includes the proper display name, consistent with the pattern shown in the storybook example.apps/storybook/.storybook/preview.tsx (2)
2-4
: Good TypeScript typing and import additions.The explicit
Decorator[]
typing and necessary imports for React and ThemeInit are properly added.
22-28
: Decorator implementation and ordering look correct.The
ThemeInit
decorator is properly placed first to establish the base configuration before the existingwithThemeByClassName
decorator applies theme switching logic. This ensures consistent theme initialization across all Storybook stories.packages/ui/src/cli/commands/register.ts (2)
10-12
: Proper setup sequence for initialization system.Moving
setupOutputDirectory()
to the beginning and addingsetupInit(config)
correctly implements the new initialization flow. This ensures the output directory exists before generating the init file.
38-38
: Simplified writeFile call is appropriate.Removing the
{ flag: "w" }
option is fine since "w" (write/overwrite) is the default behavior forfs.writeFile
.packages/ui/scripts/generate-metadata.ts (3)
238-238
: Good explicit default for prefix property.Making the empty string default explicit improves schema clarity and consistency.
252-258
: Appropriate version property definition.The version property correctly restricts values to Tailwind CSS versions 3 and 4, with a sensible default of 4. This directly addresses the tailwindcss/version.js resolution issue by making version management explicit.
260-260
: Version correctly added to required properties.Including
version
in the required array ensures all configurations explicitly specify their Tailwind CSS version, which is essential for the new initialization system.packages/ui/src/theme/config.tsx (2)
4-4
: Good interface narrowing for focused responsibility.Restricting
ThemeConfigProps
to only themode
property clarifies thatThemeConfig
is now focused solely on theme mode management, while broader configuration is handled by the newThemeInit
component.
6-7
: Implementation correctly reflects the narrowed interface.The component now properly accepts only the
mode
parameter and explicitly passes it toStoreInit
, maintaining clear separation of concerns in the new architecture.apps/web/content/docs/getting-started/cli.mdx (2)
225-227
: LGTM! Configuration example updated correctly.The addition of the
version
property with a default value of4
aligns perfectly with the new explicit Tailwind CSS version configuration approach, replacing the previous patching mechanism.
254-257
: Documentation for new version property is clear and helpful.The explanation of the
version
property is concise and accurately describes its purpose in specifying which Tailwind CSS version to use.packages/ui/src/cli/commands/ensure-tailwind.ts (3)
3-5
: Good addition of JSDoc documentation.The JSDoc comment clearly describes the function's purpose.
8-8
: Good refactoring with packageName constant.Using a constant instead of repeating string literals improves maintainability and reduces the risk of typos.
10-10
: Simplified check is cleaner and more readable.The direct boolean check is more concise than the previous approach and maintains the same functionality.
packages/ui/schema.json (3)
131-133
: Good addition of default value for prefix property.Adding the default empty string value improves the schema completeness and user experience.
144-149
: Well-designed version property definition.The version property correctly:
- Uses appropriate data type (number)
- Restricts values to supported Tailwind CSS versions (3, 4)
- Sets a sensible default (4 for latest version)
- Includes helpful description with documentation link
151-151
: Appropriate to make version a required property.Making
version
required ensures all configurations explicitly specify which Tailwind CSS version to use, which is essential for the new approach replacing the patch mechanism.packages/ui/src/store/index.ts (4)
25-31
: Well-documented version property type definition.The JSDoc documentation clearly explains the property's purpose and default value. The union type
3 | 4
correctly restricts to supported Tailwind CSS versions.
37-37
: Consistent initialization pattern.The version property follows the same initialization pattern as other store properties.
54-61
: Robust validation logic with helpful error messaging.The validation correctly:
- Checks for valid values (3 or 4)
- Provides clear warning message with available options
- Follows the same pattern as the mode property validation
75-77
: Consistent getter function implementation.The
getVersion
function follows the same pattern as other getter functions in the store.apps/web/content/docs/customize/prefix.mdx (3)
22-24
: Config example correctly updated with version property.The addition of
"version": 4
in the configuration example is consistent with the schema changes and new explicit versioning approach.
53-53
: Clear explanation of when ThemeInit is required.The documentation clearly explains that
ThemeInit
is needed when using custom configuration, which helps users understand when this component is necessary.
55-67
: Updated example correctly demonstrates new ThemeInit usage.The code example properly shows:
- Correct import path from the auto-generated init file
- Proper placement at the root level
- Simple usage without props (configuration comes from the config file)
apps/storybook/.flowbite-react/init.tsx (3)
9-10
: LGTM!The imports are correct and necessary for the component implementation.
12-16
: LGTM!The configuration object follows the established pattern and contains appropriate values for the Storybook environment.
18-22
: LGTM!The component implementation is clean and follows React best practices. The displayName assignment is helpful for debugging.
packages/ui/src/cli/utils/get-module-package-json.ts (2)
1-11
: LGTM!The function signature and generic type constraint are well-designed, ensuring type safety while allowing flexibility for different package.json structures.
12-15
: LGTM!The primary resolution method using createRequire is well-implemented and should handle most cases reliably.
packages/ui/src/cli/commands/init.ts (3)
2-2
: LGTM!The new imports for
installPackage
andsetupInit
are appropriate and align with the refactored initialization flow.Also applies to: 6-6
16-16
: LGTM!The refactored initialization sequence is logical and well-structured. Storing the config result and passing it to
setupInit
enables proper runtime configuration synchronization.Also applies to: 20-21
22-23
: LGTM!The reordering of setup calls maintains logical flow and the new sequence is appropriate for the refactored initialization process.
apps/web/content/docs/customize/config.mdx (4)
43-44
: LGTM!The schema updates are well-structured. The version property with enum constraints and the explicit default for prefix improve configuration clarity and validation.
Also applies to: 56-63
111-117
: LGTM!The documentation for the version property is clear, informative, and follows the established format for other configuration properties.
137-144
: LGTM!The configuration examples are properly updated to include the version property and maintain consistency with the schema definition.
Also applies to: 160-167
56-167
: Excellent documentation update supporting the new version configuration.The documentation comprehensively covers the new version property with clear schema definition, detailed explanations, and consistent examples. This supports the broader refactoring and new runtime initialization approach.
packages/ui/src/cli/commands/setup-gitignore.ts (3)
2-2
: LGTM!Using imported constants improves maintainability and consistency. The centralized approach eliminates hardcoded strings and path construction.
Also applies to: 11-11
4-9
: LGTM!The updated JSDoc documentation is comprehensive and clearly explains the function's purpose and behavior.
14-19
: LGTM!The refactored file reading logic using try-catch is cleaner and more readable than the previous promise-based approach.
packages/ui/src/cli/consts.ts (3)
5-6
: LGTM: New file constants are well-defined.The new
gitIgnoreFile
andinitFile
constants follow the existing pattern and correctly define the base filenames for the new initialization system.
16-18
: LGTM: Path constants are properly constructed.The new path constants follow the established pattern and correctly support both TypeScript (.tsx) and JavaScript (.jsx) versions of the initialization file.
9-10
: LGTM: Constants reorganization is harmless.The moved
pluginName
andpluginPath
constants retain their correct values and this appears to be a simple reorganization for better logical grouping.packages/ui/src/cli/commands/build.ts (2)
1-7
: LGTM: Imports align with new build functionality.The new imports support the refactored build process including configuration loading, initialization setup, and component extraction logic.
13-48
: Component extraction logic is well-covered by tests
TheextractComponentImports
utility includes comprehensive tests for:
• Single, multiple, aliased, and star imports
• Subpath imports (e.g.flowbite-react/lib/components
)
• Filtering invalid names
No further changes are needed.packages/ui/src/cli/utils/build-class-list.ts (1)
74-81
: LGTM: Version parameter usage is correct.The explicit version parameter is properly used in both the utility conversion logic and prefix application, maintaining the same conditional behavior as the previous implementation.
packages/ui/src/cli/commands/install.ts (2)
22-35
: LGTM: Version checking logic is well-implemented.The logic correctly checks package dependencies, performs proper semantic version comparison, and efficiently handles the update-or-skip decision. The 0.11 version threshold aligns with the introduction of the new CLI system.
37-44
: LGTM: Installation flow follows best practices.The installation logic properly resolves package manager commands, provides user feedback, handles async operations correctly, and includes appropriate error handling with consistent messaging.
.changeset/tricky-planes-shake.md (1)
1-29
: LGTM: Comprehensive and clear changeset documentation.The changeset properly documents the breaking changes, explains the new system clearly, and provides actionable migration steps with specific code examples. The documentation aligns well with the implemented changes.
packages/ui/src/cli/utils/get-config.ts (1)
1-15
: LGTM! Clean delegation pattern.The refactoring to delegate all configuration management to
setupConfig
simplifies the code and creates a clear separation of concerns. The documentation accurately reflects the new behavior.packages/ui/package.json (1)
165-184
: New store exports properly configured.The addition of
./store
and./store/init
exports follows the established pattern with proper TypeScript declarations for both ESM and CommonJS environments. This supports the newThemeInit
component initialization system.packages/ui/src/cli/commands/dev.ts (4)
25-27
: Proper initialization sequence established.The addition of
setupOutputDirectory()
ensures the output directory exists before proceeding, andsetupInit(config)
generates the initialization file based on the loaded configuration. This establishes a clear initialization flow.
37-62
: Well-structured initial file scanning.The initial scan properly:
- Uses
findFiles
utility to discover all relevant files- Extracts component imports from each file
- Builds the class list based on discovered or configured components
- Only writes the class list file if it differs from the existing one
82-88
: Smart configuration hot-reloading implemented.The watcher now properly handles changes to configuration-related files by:
- Reloading config when
config.json
or init files change- Re-running
setupInit
to regenerate the initialization file- Updating
.gitignore
when neededThis enables a smooth development experience with automatic synchronization.
115-115
: Good optimization withignoreInitial: true
.Setting
ignoreInitial: true
prevents the watcher from firing events for all existing files on startup, avoiding duplicate processing since the initial scan already handles existing files.apps/web/content/docs/customize/dark-mode.mdx (1)
58-96
: Documentation accurately reflects the new configuration approach.The updated documentation:
- Clearly explains the two-step process for disabling dark mode
- Shows the required
version
property in the config example- Provides proper usage example for the
ThemeInit
component- Includes an important note explaining the distinction between build-time and runtime configuration
The changes align perfectly with the new architecture that removes the patch mechanism in favor of explicit configuration.
packages/ui/src/cli/commands/setup-config.ts (2)
105-116
: Excellent user guidance for custom configurations.The informative messages clearly explain:
- When
ThemeInit
is required (custom values detected)- Why it's necessary (runtime sync with build config)
- What happens without it (default values used)
- Concrete example of the impact (incorrect class names)
This proactive guidance will help prevent configuration issues.
19-129
: Robust configuration management implementation.The
setupConfig
function provides comprehensive configuration handling:
- ✅ Deep validation of all properties with type checking
- ✅ Sanitization of invalid values with defaults
- ✅ Removal of unknown properties
- ✅ Key ordering for consistency
- ✅ Clear error messages and user guidance
- ✅ Proper error handling for missing/invalid files
This implementation successfully replaces the previous patch-based approach with a more maintainable configuration system.
packages/ui/src/cli/commands/setup-init.ts (2)
1-11
: LGTM: Clean imports and good documentation.The imports are appropriate and the JSDoc documentation clearly explains the function's purpose.
72-104
: LGTM: Well-implemented AST comparison function.The
compareNodes
function is thoughtfully designed to compare AST nodes while ignoring irrelevant metadata like location information and comments. The recursive approach handles all data types correctly, and the filtered properties list is comprehensive for typical AST structures.
…and fix dark theme toggle class in Tailwind CSS v4 - Introduced `version` parameter to `buildClassList` and `ThemeModeScript` for Tailwind CSS versioning. - Updated dark mode class handling based on the specified version in `setModeInDOM` and related functions. - Adjusted tests to verify prefix behavior according to the Tailwind CSS version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
apps/web/.flowbite-react/init.tsx (1)
3-3
: The biome-ignore syntax is already correct.Based on previous discussion and verification with Biome documentation, the current syntax
// biome-ignore-all lint: auto-generated file
is correct for disabling all lint rules file-wide. The static analysis error appears to be from an outdated tool version.apps/storybook/.flowbite-react/init.tsx (1)
3-3
: The biome-ignore syntax is correct.Same as in the web app version - the current syntax follows Biome documentation standards. The static analysis tool error appears to be from an outdated version.
🧹 Nitpick comments (1)
packages/ui/src/cli/commands/setup-init.ts (1)
41-70
: Consider the timing between file writes and cleanup operations.While the setTimeout debouncing for file writes is correct (as noted in learnings), there's a potential race condition where the cleanup of the old file (lines 60-66) could execute before the new file write completes, since setTimeout operations are not awaited.
Consider adding a small delay before cleanup or restructuring to ensure file writes complete first:
try { let currentContent = ""; try { currentContent = await fs.readFile(targetPath, "utf-8"); } catch { console.log(`Creating ${targetPath} file...`); - setTimeout(() => fs.writeFile(targetPath, content), 10); + setTimeout(async () => { + await fs.writeFile(targetPath, content); + // Cleanup after write completes + await cleanupOldFile(oldPath); + }, 10); + return; // Skip cleanup below since it's handled in timeout } if (currentContent) { const currentAst = parse(currentContent); const newAst = parse(content); if (!compareNodes(currentAst.program, newAst.program)) { console.log(`Updating ${targetPath} file...`); - setTimeout(() => fs.writeFile(targetPath, content), 10); + setTimeout(async () => { + await fs.writeFile(targetPath, content); + // Cleanup after write completes + await cleanupOldFile(oldPath); + }, 10); + return; // Skip cleanup below since it's handled in timeout } } - try { - await fs.access(oldPath); - console.log(`Removing ${oldPath} file...`); - await fs.unlink(oldPath); - } catch { - // noop - } + // Cleanup for cases where no file write was needed + await cleanupOldFile(oldPath); } catch (error) { console.error(`Failed to update ${targetPath}:`, error); }And add the helper function:
async function cleanupOldFile(oldPath: string) { try { await fs.access(oldPath); console.log(`Removing ${oldPath} file...`); await fs.unlink(oldPath); } catch { // noop } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.changeset/tricky-planes-shake.md
(1 hunks)apps/storybook/.flowbite-react/config.json
(1 hunks)apps/storybook/.flowbite-react/init.tsx
(1 hunks)apps/web/.flowbite-react/config.json
(1 hunks)apps/web/.flowbite-react/init.tsx
(1 hunks)packages/ui/src/cli/commands/setup-init.ts
(1 hunks)
🧠 Learnings (3)
packages/ui/src/cli/commands/setup-init.ts (1)
Learnt from: SutuSebastian
PR: #1566
File: packages/ui/src/cli/commands/setup-init.ts:41-0
Timestamp: 2025-07-21T18:57:15.331Z
Learning: In CLI tools that generate files, using setTimeout with a small delay (like 10ms) before fs.writeFile operations can be intentional debouncing to prevent race conditions with IDE formatting extensions (Prettier, ESLint auto-fix, etc.) that automatically format files upon creation/modification. This ensures the file is visible to the IDE and formatting completes before proceeding with subsequent operations.
apps/storybook/.flowbite-react/init.tsx (1)
Learnt from: SutuSebastian
PR: #1566
File: apps/web/.flowbite-react/init.tsx:0-0
Timestamp: 2025-07-21T18:59:04.117Z
Learning: The correct Biome ignore syntax for disabling all lint rules in a file is // biome-ignore-all lint: <optional reason>
, not // biome-ignore lint/all:
as I previously suggested.
apps/web/.flowbite-react/init.tsx (1)
Learnt from: SutuSebastian
PR: #1566
File: apps/web/.flowbite-react/init.tsx:0-0
Timestamp: 2025-07-21T18:59:04.117Z
Learning: The correct Biome ignore syntax for disabling all lint rules in a file is // biome-ignore-all lint: <optional reason>
, not // biome-ignore lint/all:
as I previously suggested.
🧬 Code Graph Analysis (1)
apps/storybook/.flowbite-react/init.tsx (1)
apps/web/.flowbite-react/init.tsx (2)
config
(12-16)ThemeInit
(18-20)
🪛 Biome (1.9.4)
apps/storybook/.flowbite-react/init.tsx
[error] 3-3: failed to parse category "-all"
(suppressions/parse)
apps/web/.flowbite-react/init.tsx
[error] 3-3: failed to parse category "-all"
(suppressions/parse)
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/.flowbite-react/config.json
- apps/storybook/.flowbite-react/config.json
- .changeset/tricky-planes-shake.md
🧰 Additional context used
🧠 Learnings (3)
packages/ui/src/cli/commands/setup-init.ts (1)
Learnt from: SutuSebastian
PR: #1566
File: packages/ui/src/cli/commands/setup-init.ts:41-0
Timestamp: 2025-07-21T18:57:15.331Z
Learning: In CLI tools that generate files, using setTimeout with a small delay (like 10ms) before fs.writeFile operations can be intentional debouncing to prevent race conditions with IDE formatting extensions (Prettier, ESLint auto-fix, etc.) that automatically format files upon creation/modification. This ensures the file is visible to the IDE and formatting completes before proceeding with subsequent operations.
apps/storybook/.flowbite-react/init.tsx (1)
Learnt from: SutuSebastian
PR: #1566
File: apps/web/.flowbite-react/init.tsx:0-0
Timestamp: 2025-07-21T18:59:04.117Z
Learning: The correct Biome ignore syntax for disabling all lint rules in a file is // biome-ignore-all lint: <optional reason>
, not // biome-ignore lint/all:
as I previously suggested.
apps/web/.flowbite-react/init.tsx (1)
Learnt from: SutuSebastian
PR: #1566
File: apps/web/.flowbite-react/init.tsx:0-0
Timestamp: 2025-07-21T18:59:04.117Z
Learning: The correct Biome ignore syntax for disabling all lint rules in a file is // biome-ignore-all lint: <optional reason>
, not // biome-ignore lint/all:
as I previously suggested.
🧬 Code Graph Analysis (1)
apps/storybook/.flowbite-react/init.tsx (1)
apps/web/.flowbite-react/init.tsx (2)
config
(12-16)ThemeInit
(18-20)
🪛 Biome (1.9.4)
apps/storybook/.flowbite-react/init.tsx
[error] 3-3: failed to parse category "-all"
(suppressions/parse)
apps/web/.flowbite-react/init.tsx
[error] 3-3: failed to parse category "-all"
(suppressions/parse)
🔇 Additional comments (7)
apps/web/.flowbite-react/init.tsx (3)
5-8
: Excellent documentation for auto-generated file.Clear and helpful comments that properly warn users not to edit this file directly and guide them to the correct configuration file.
9-16
: Clean implementation of the new store initialization system.The imports and configuration structure align with the new theme initialization approach. The
version: 3
property correctly implements the new required configuration schema.
18-22
: Well-implemented React component.The
ThemeInit
component cleanly wrapsStoreInit
with the configuration props. Setting thedisplayName
is good practice for debugging with React DevTools.apps/storybook/.flowbite-react/init.tsx (1)
1-22
: Consistent auto-generated file structure across applications.This file maintains identical structure and configuration to
apps/web/.flowbite-react/init.tsx
, ensuring consistent theming between the web application and Storybook. The auto-generation process correctly produces uniform output across different app contexts.packages/ui/src/cli/commands/setup-init.ts (3)
1-12
: LGTM! Clean imports and well-documented function.The imports are appropriate and the JSDoc documentation clearly explains the function's purpose and behavior.
13-40
: Well-structured content generation and file path logic.The template string correctly embeds configuration values, includes appropriate linting directives for auto-generated files, and the file path logic properly handles TypeScript/JavaScript variants.
72-104
: Excellent AST comparison implementation.The
compareNodes
function is well-designed with proper handling of different data types, comprehensive filtering of location/comment metadata, and efficient recursive comparison. The approach correctly identifies meaningful structural differences while ignoring parser artifacts.
Breaking changes
flowbite-react patch
CLI commandChanges
flowbite-react/.gitignore
,flowbite-react/config.json
,flowbite-react/init.(jsx|tsx)
self manages, regenerates and repairsinit.(jsx|tsx)
in.flowbite-react/
directory that syncs up values fromconfig.json
that also are needed in React app runtime (similar to how a React context works)init
,build
,dev
,register
<ThemeInit />
at the root level if customdark
,prefix
, orversion
values are detected in the configuration fileflowbite-react/store
import pathflowbite-react
is installed whennpx flowbite-react@latest init
0.11.x
{ flag: "w" }
infs.writeFile
dark-mode.md
andprefix.md
documentation to reflect the<ThemeInit />
changesMigration Guide
Remove
flowbite-react patch
from yourpackage.json
{ "scripts": { - "postinstall": "flowbite-react patch" } }
Add
<ThemeInit />
(import from.flowbite-react/init.(jsx|tsx)
) at the root level of your app if you have custom configuration in.flowbite-react/config.json
(differentdark
/prefix
/version
values).Summary by CodeRabbit
Summary by CodeRabbit
New Features
version
property in configuration files to specify Tailwind CSS version (3 or 4).<ThemeInit />
React component for synchronizing runtime configuration with project settings; users with custom configurations must render this at the app root.Breaking Changes
flowbite-react patch
CLI command and related patching logic..gitignore
and configuration files are now self-managed and auto-regenerating.<ThemeInit />
.Documentation
<ThemeInit />
.Chores
Refactor
Bug Fixes